const { query, transaction, formatRows, buildWhereClause } = require('../config/database');
const Appointment = require('./Appointment');

class Application {
  // 创建申请
  static async create(applicationData) {
    const { appointment_id, applicant_id, reason } = applicationData;
    
    // 检查预约是否存在
    const appointment = await Appointment.findById(appointment_id);
    if (!appointment) {
      throw new Error('预约不存在');
    }
    
    // 检查预约是否已满员
    if (appointment.current_players >= appointment.max_players) {
      throw new Error('预约已满员');
    }
    
    // 检查用户是否已参与
    const isParticipant = await Appointment.isUserParticipant(appointment_id, applicant_id);
    if (isParticipant) {
      throw new Error('您已经参与了此预约');
    }
    
    // 检查是否已有待处理的申请
    const existingApplication = await this.findByAppointmentAndUser(appointment_id, applicant_id);
    if (existingApplication && existingApplication.status === 'pending') {
      throw new Error('您已经申请过此预约，请等待处理');
    }
    
    const sql = `
      INSERT INTO applications (appointment_id, applicant_id, reason)
      VALUES (?, ?, ?)
    `;
    
    const result = await query(sql, [appointment_id, applicant_id, reason]);
    return await this.findById(result.insertId);
  }
  
  // 根据ID查找申请
  static async findById(id) {
    const sql = `
      SELECT 
        app.*,
        u.username as applicant_username,
        u.nickname as applicant_nickname,
        u.avatar_url as applicant_avatar,
        a.title as appointment_title,
        a.game_name,
        a.creator_id as appointment_creator_id,
        processor.username as processor_username
      FROM applications app
      JOIN users u ON app.applicant_id = u.id
      JOIN appointments a ON app.appointment_id = a.id
      LEFT JOIN users processor ON app.processed_by = processor.id
      WHERE app.id = ?
    `;
    
    const rows = await query(sql, [id]);
    return rows.length > 0 ? formatRows(rows)[0] : null;
  }
  
  // 根据预约和用户查找申请
  static async findByAppointmentAndUser(appointmentId, userId) {
    const sql = `
      SELECT 
        app.*,
        u.username as applicant_username,
        u.nickname as applicant_nickname,
        u.avatar_url as applicant_avatar
      FROM applications app
      JOIN users u ON app.applicant_id = u.id
      WHERE app.appointment_id = ? AND app.applicant_id = ?
      ORDER BY app.applied_at DESC
      LIMIT 1
    `;
    
    const rows = await query(sql, [appointmentId, userId]);
    return rows.length > 0 ? formatRows(rows)[0] : null;
  }
  
  // 获取申请列表
  static async getList(conditions = {}, page = 1, limit = 10) {
    const { clause, params } = buildWhereClause(conditions);
    
    // 获取总数
    const countSql = `
      SELECT COUNT(*) as total 
      FROM applications app
      JOIN users u ON app.applicant_id = u.id
      JOIN appointments a ON app.appointment_id = a.id
      ${clause}
    `;
    
    const countResult = await query(countSql, params);
    const total = countResult[0].total;
    
    // 获取列表数据
    const offset = (page - 1) * limit;
    const listSql = `
      SELECT 
        app.*,
        u.username as applicant_username,
        u.nickname as applicant_nickname,
        u.avatar_url as applicant_avatar,
        a.title as appointment_title,
        a.game_name,
        a.creator_id as appointment_creator_id,
        processor.username as processor_username
      FROM applications app
      JOIN users u ON app.applicant_id = u.id
      JOIN appointments a ON app.appointment_id = a.id
      LEFT JOIN users processor ON app.processed_by = processor.id
      ${clause}
      ORDER BY app.applied_at DESC
      LIMIT ${limit} OFFSET ${offset}
    `;
    
    const rows = await query(listSql, params);
    
    return {
      data: formatRows(rows),
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit)
      }
    };
  }
  
  // 处理申请（通过或拒绝）
  static async process(applicationId, status, processedBy, adminNotes = '') {
    if (!['approved', 'rejected'].includes(status)) {
      throw new Error('无效的处理状态');
    }
    
    const application = await this.findById(applicationId);
    if (!application) {
      throw new Error('申请不存在');
    }
    
    if (application.status !== 'pending') {
      throw new Error('申请已被处理');
    }
    
    // 检查处理者是否为预约创建者
    if (application.appointment_creator_id !== processedBy) {
      throw new Error('只有预约创建者可以处理申请');
    }
    
    return await transaction(async (connection) => {
      // 更新申请状态
      const updateSql = `
        UPDATE applications 
        SET status = ?, processed_at = CURRENT_TIMESTAMP, 
            processed_by = ?, admin_notes = ?
        WHERE id = ?
      `;
      
      await connection.execute(updateSql, [status, processedBy, adminNotes, applicationId]);
      
      // 如果通过申请，将用户添加为参与者
      if (status === 'approved') {
        try {
          await Appointment.addParticipant(
            application.appointment_id, 
            application.applicant_id, 
            'participant'
          );
        } catch (error) {
          // 如果添加参与者失败（比如已满员），回滚申请状态
          throw new Error('添加参与者失败：' + error.message);
        }
      }
      
      return await this.findById(applicationId);
    });
  }
  
  // 取消申请
  static async cancel(applicationId, userId) {
    const application = await this.findById(applicationId);
    if (!application) {
      throw new Error('申请不存在');
    }
    
    if (application.applicant_id !== userId) {
      throw new Error('只能取消自己的申请');
    }
    
    if (application.status !== 'pending') {
      throw new Error('只能取消待处理的申请');
    }
    
    const sql = `
      UPDATE applications 
      SET status = 'cancelled', processed_at = CURRENT_TIMESTAMP
      WHERE id = ?
    `;
    
    await query(sql, [applicationId]);
    return await this.findById(applicationId);
  }
  
  // 获取用户的申请列表
  static async getUserApplications(userId, page = 1, limit = 10) {
    return await this.getList(
      { 'app.applicant_id': userId },
      page,
      limit
    );
  }
  
  // 获取预约的申请列表
  static async getAppointmentApplications(appointmentId, page = 1, limit = 10) {
    return await this.getList(
      { 'app.appointment_id': appointmentId },
      page,
      limit
    );
  }
  
  // 获取待处理的申请数量
  static async getPendingCount(creatorId) {
    const sql = `
      SELECT COUNT(*) as count
      FROM applications app
      JOIN appointments a ON app.appointment_id = a.id
      WHERE a.creator_id = ? AND app.status = 'pending'
    `;
    
    const rows = await query(sql, [creatorId]);
    return rows[0].count;
  }
}

module.exports = Application;
